package com.youhome.service.service.impl;


import com.github.pagehelper.PageInfo;
import com.google.common.base.Ascii;
import com.youhome.common.config.SolrConfig;
import com.youhome.common.enums.HouseDataSourceEnum;
import com.youhome.common.exception.CustomException;
import com.youhome.common.response.Result;
import com.youhome.common.response.ResultCode;
import com.youhome.common.response.ResultPage;
import com.youhome.service.mapper.HotCityMapper;
import com.youhome.service.mapper.ZipMapper;
import com.youhome.service.model.*;
import com.youhome.service.parameter.ParamHouseMapSearch;
import com.youhome.service.parameter.ParamHouseSearch;
import com.youhome.service.response.AssociateResult;
import com.youhome.service.response.InterestPointResult;
import com.youhome.service.response.Poi;
import com.youhome.service.service.*;
import com.youhome.utils.GeoUtils;
import com.youhome.utils.SolrUtils;
import com.youhome.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.*;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by chen365 on 2018/07/20.
 */
@Service
@Slf4j
public class SolrServiceImpl implements SolrService {
    @Autowired
    private SolrConfig solrConfig;
    @Autowired
    private ZipMapper zipMapper;
    @Autowired
    private HotCityMapper hotCityMapper;
    @Autowired
    private ListHubService listHubService;
    @Autowired
    private BUserService bUserService;
    @Autowired
    private BCompanyService bCompanyService;
    @Autowired
    private BCounselorService bCounselorService;
    @Autowired
    private BShareGroupService bShareGroupService;
    @Autowired
    private GeoService geoService;
    @Value("${solr.host}")
    private String solrHost;


    public static String transformMetachar(String input) {
        StringBuffer sb = new StringBuffer();
        try {
            String regex = "[+\\-&|!(){}\\[\\]^\"~*?:(\\)\\s]";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(input);
            while (matcher.find()) {
                matcher.appendReplacement(sb, "\\\\" + matcher.group());
            }
            matcher.appendTail(sb);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    @Override
    public List<InterestPointResult> selectPoiByCoordinateAndDist(Double lat, Double lng, Double dist) {

        String point = lng + " " + lat;

        List<InterestPointResult> list = new ArrayList<>();
        SolrDocumentList documents = null;
        long time = System.currentTimeMillis();
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrConfig.getHost())
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();

            final Map<String, String> queryParamMap = new HashMap<>();

            queryParamMap.put("q", "*:*");
            queryParamMap.put("fl", "*,_dist_:geodist()"); //查询的结果中添加距离
            queryParamMap.put("fq", "{!geofilt}"); //距离过滤函数
            queryParamMap.put("pt", point); //当前经纬度
            queryParamMap.put("sfield", "point"); //经纬度的字段
            queryParamMap.put("d", dist.toString()); //千米

            queryParamMap.put("start", "0");//记录开始位置
            queryParamMap.put("rows", "10000");//查询的行数

            queryParamMap.put("sort", "geodist() asc");  //根据距离排序：由近到远

            MapSolrParams mapSolrParams = new MapSolrParams(queryParamMap);
            final QueryResponse response = httpSolrClient.query("poi", mapSolrParams);
            documents = response.getResults();

            System.err.println("数量：" + documents.getNumFound());
            System.err.println("solr-time--1:" + (System.currentTimeMillis() - time));
            for (SolrDocument solrDocument : documents) {
                Poi poi = SolrUtils.solrDocumentToPojo(solrDocument, Poi.class);

                InterestPointResult poiResult = new InterestPointResult();

                poiResult.setName(poi.getName());

                List<String> address = new ArrayList<>();
                if (poi.getDelivery_line() != null) {
                    address.add(poi.getDelivery_line());
                }
                if (poi.getCity() != null) {
                    address.add(poi.getCity());
                }
                if (poi.getState() != null) {
                    address.add(poi.getState());
                }
                if (poi.getZip() != null) {
                    address.add(poi.getZip());
                }
                if (address.size() > 0) {
                    poiResult.setAddress(String.join(", ", address));
                }
                if (poi.getPhone() != null) {
                    poiResult.setPhone(poi.getPhone());
                }
                if (poi.getLatitude() != null) {
                    poiResult.setLatitude(poi.getLatitude());
                }
                if (poi.getLongitude() != null) {
                    poiResult.setLongitude(poi.getLongitude());
                }
                if (poi.getPrimary() != null) {
                    poiResult.setCategories(new HashSet(poi.getPrimary()));
                }
                list.add(poiResult);
            }

            httpSolrClient.close();
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.err.println("solr-time:" + (System.currentTimeMillis() - time));

        return list;
    }

    @Override
    public List<InterestPointResult> selectPoiByCoordinateAndDist(String polygon, Integer dist) {
        //q=*:*&rows=100&

        List<InterestPointResult> list = new ArrayList<>();
        SolrDocumentList documents = null;
        long time = System.currentTimeMillis();
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrConfig.getHost())
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();

            final Map<String, String> queryParamMap = new HashMap<>();

            queryParamMap.put("q", "*:*");
            queryParamMap.put("fq", "{!field f=point}Intersects(POLYGON((" + polygon + ")))"); //距离过滤函数

            //queryParamMap.put("start", "0");//记录开始位置
            queryParamMap.put("rows", "10000");//查询的行数

            for (String key : queryParamMap.keySet()) {
                System.out.println("Key: " + key + " Value: " + queryParamMap.get(key));
            }

            MapSolrParams mapSolrParams = new MapSolrParams(queryParamMap);
            final QueryResponse response = httpSolrClient.query("poi", mapSolrParams);

            documents = response.getResults();
            System.err.println("数量：" + documents.getNumFound());
            System.err.println("solr-time--1:" + (System.currentTimeMillis() - time));
            for (SolrDocument solrDocument : documents) {
                Poi poi = SolrUtils.solrDocumentToPojo(solrDocument, Poi.class);

                InterestPointResult poiResult = new InterestPointResult();

                poiResult.setName(poi.getName());

                List<String> address = new ArrayList<>();
                if (poi.getDelivery_line() != null) {
                    address.add(poi.getDelivery_line());
                }
                if (poi.getCity() != null) {
                    address.add(poi.getCity());
                }
                if (poi.getState() != null) {
                    address.add(poi.getState());
                }
                if (poi.getZip() != null) {
                    address.add(poi.getZip());
                }
                if (address.size() > 0) {
                    poiResult.setAddress(String.join(", ", address));
                }
                if (poi.getPhone() != null) {
                    poiResult.setPhone(poi.getPhone());
                }
                if (poi.getLatitude() != null) {
                    poiResult.setLatitude(poi.getLatitude());
                }
                if (poi.getLongitude() != null) {
                    poiResult.setLongitude(poi.getLongitude());
                }
                if (poi.getPrimary() != null) {
                    poiResult.setCategories(new HashSet(poi.getPrimary()));
                }
                list.add(poiResult);
            }

            httpSolrClient.close();
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.err.println("solr-time:" + (System.currentTimeMillis() - time));

        if (!StringUtils.isEmpty(dist) && dist > 0) {
            System.err.println("before list-size:" + list.size());
            Long densitytime = System.currentTimeMillis();
            list = density(list, dist);
            System.err.println("density-time:" + (System.currentTimeMillis() - densitytime));
            System.err.println("after list-size:" + list.size());
        }

        return list;
    }

    public List<InterestPointResult> density(List<InterestPointResult> list, int dist) {
        List<InterestPointResult> rows = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                if (i == 0) {
                    rows.add(list.get(i));
                } else {
                    Boolean flag = true;
                    Double lat = list.get(i).getLatitude();
                    Double lng = list.get(i).getLongitude();
                    for (InterestPointResult item : rows) {
                        Double lat2 = item.getLatitude();
                        Double lng2 = item.getLongitude();
                        double distance = GeoUtils.getDistance(lat, lng, lat2, lng2);
//                        System.err.println("lat:" + lat + "===>>lng:" + lng + "===>>lat2:" + lat2 + "====>>lng2:" + lng2);
//                        System.err.println("distance:" + distance);
                        if (distance < dist) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {
                        rows.add(list.get(i));
                    }
                }
            }
        }
        return rows;
    }

    @Override
    public List<AssociateZip> associateSearchByZip(String zip) {
        List<AssociateZip> associateZips = new ArrayList<>();
        long time = System.currentTimeMillis();
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrConfig.getHost())
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();

            final Map<String, String> queryParamMap = new HashMap<>();
            if (!StringUtils.isEmpty(zip)) {
                zip = transformMetachar(zip) + "*";
            }
            queryParamMap.put("q", "zip:" + zip);
            queryParamMap.put("fl", "city,zip");
            queryParamMap.put("group", "true");
            queryParamMap.put("group.field", "zip");
            queryParamMap.put("start", "0");//记录开始位置
            queryParamMap.put("rows", "20");//查询的行数

            MapSolrParams mapSolrParams = new MapSolrParams(queryParamMap);
            final QueryResponse response = httpSolrClient.query("listhub", mapSolrParams);
            GroupResponse groupResponse = response.getGroupResponse();
            System.err.println("size:" + groupResponse.getValues().size());
            for (GroupCommand groupCommand : groupResponse.getValues()) {
                List<Group> values = groupCommand.getValues();
                for (Group group : values) {
                    SolrDocumentList result = group.getResult();

                    for (SolrDocument solrDocument : result) {
                        System.err.println("solrDocument" + solrDocument.toString());
                        AssociateZip associateZip = SolrUtils.solrDocumentToPojo(solrDocument, AssociateZip.class);
                        associateZips.add(associateZip);
                    }
                }
            }
            /*
            SolrDocumentList documents = response.getResults();
            System.err.println("数量：" + documents.getNumFound());
            System.err.println("solr-time--1:" + (System.currentTimeMillis() - time));

            for (SolrDocument solrDocument : documents) {
                System.err.println(solrDocument);
                AssociateZip associateZip = SolrUtils.solrDocumentToPojo(solrDocument, AssociateZip.class);
                associateZips.add(associateZip);
            }
            */


        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.err.println("solr-time:" + (System.currentTimeMillis() - time));

        return associateZips;

    }

    @Override
    public List<AssociateCity> associateSearchByCity(String city) {
        List<AssociateCity> associateCities = new ArrayList<>();
        long time = System.currentTimeMillis();
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrConfig.getHost())
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();

            final Map<String, String> queryParamMap = new HashMap<>();
            if (!StringUtils.isEmpty(city)) {
                city = "*" + transformMetachar(city) + "*";
            }
            System.err.println(city);
            queryParamMap.put("q", "city:" + city);
            queryParamMap.put("fl", "city,province");
            queryParamMap.put("group", "true");
            queryParamMap.put("group.field", "city");
            queryParamMap.put("start", "0");//记录开始位置
            queryParamMap.put("rows", "20");//查询的行数

            MapSolrParams mapSolrParams = new MapSolrParams(queryParamMap);
            System.err.println(mapSolrParams.toQueryString());

            final QueryResponse response = httpSolrClient.query("listhub", mapSolrParams);

            GroupResponse groupResponse = response.getGroupResponse();
            System.err.println("size:" + groupResponse.getValues().size());
            for (GroupCommand groupCommand : groupResponse.getValues()) {
                List<Group> values = groupCommand.getValues();
                for (Group group : values) {
                    SolrDocumentList result = group.getResult();

                    for (SolrDocument solrDocument : result) {
                        System.err.println("solrDocument" + solrDocument.toString());
                        AssociateCity associateCity = new AssociateCity();//SolrUtils.solrDocumentToPojo(solrDocument, AssociateCity.class);
                        if (solrDocument.get("city") != null) {
                            associateCity.setCity(solrDocument.get("city").toString());
                        }
                        if (solrDocument.get("province") != null) {
                            associateCity.setState(solrDocument.get("province").toString());
                        }
                        associateCities.add(associateCity);
                    }
                }
            }

            /*
            SolrDocumentList documents = response.getResults();
            System.err.println("数量：" + documents.getNumFound());
            System.err.println("solr-time--1:" + (System.currentTimeMillis() - time));

            for (SolrDocument solrDocument : documents) {
                AssociateCity associateZip = SolrUtils.solrDocumentToPojo(solrDocument, AssociateCity.class);
                associateCities.add(associateZip);
            }
            */

        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.err.println("solr-time:" + (System.currentTimeMillis() - time));

        return associateCities;
    }

    @Override
    public List<AssociateAddress> associateSearchByAddress(String address) {
        List<AssociateAddress> associateAddresses = new ArrayList<>();
        long time = System.currentTimeMillis();
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrConfig.getHost())
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();

            final Map<String, String> queryParamMap = new HashMap<>();
            if (!StringUtils.isEmpty(address)) {
                address = "*" + transformMetachar(address) + "*";
            }
            System.err.println(address);
            queryParamMap.put("q", "address:" + address);
            //queryParamMap.put("q", "address:*new\\ yor*");
            queryParamMap.put("fl", "id,address");
            queryParamMap.put("start", "0");//记录开始位置
            queryParamMap.put("rows", "20");//查询的行数

            MapSolrParams mapSolrParams = new MapSolrParams(queryParamMap);

            System.err.println(mapSolrParams.toQueryString());

            final QueryResponse response = httpSolrClient.query("listhub", mapSolrParams);

            SolrDocumentList documents = response.getResults();

            System.err.println("数量：" + documents.getNumFound());
            System.err.println("solr-time--1:" + (System.currentTimeMillis() - time));

            for (SolrDocument solrDocument : documents) {
                AssociateAddress associateAddress = new AssociateAddress();// SolrUtils.solrDocumentToPojo(solrDocument, AssociateAddress.class);

                if (solrDocument.get("id") != null) {
                    associateAddress.setHouseId(solrDocument.get("id").toString());
                }
                if (solrDocument.get("address") != null) {
                    associateAddress.setAddress(solrDocument.get("address").toString());
                }
                associateAddresses.add(associateAddress);
            }

        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.err.println("solr-time:" + (System.currentTimeMillis() - time));

        return associateAddresses;
    }

    @Override
    public PageInfo<ListHubList> searchByZipOfApi(String zip,Integer pageNumber,Integer pageSize)  throws CustomException {

        if (StringUtils.isEmpty(zip)) {
            throw  new CustomException(ResultCode.EMPTY_ZIPCODE);
        }
        if (zip.length() != 5) {
            throw new CustomException(ResultCode.ERROR_ZIPCODE_LENGTH);
        }
        if (zip.equals("00000") || zip.equals("99999")) {
            return null;
        }
        if (StringUtils.isEmpty(pageNumber) || pageNumber < 1) {
            pageNumber = 1;
        }
        if (StringUtils.isEmpty(pageSize) || pageSize < 10) {
            pageSize = 10;
        }

        long total = 0;

        List<ListHubList> lists = new ArrayList<>();
        long time = System.currentTimeMillis();
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrConfig.getHost())
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();

            final Map<String, String> queryParamMap = new HashMap<>();
            SolrQuery filterQuery = new SolrQuery();

            Integer start = (pageNumber - 1) * pageSize;

            queryParamMap.put("q", "zip:" + zip);

            filterQuery.setSort("year_built", SolrQuery.ORDER.desc);

            filterQuery.addFilterQuery("enabled:true");
            String listingStatus = "Active";
            filterQuery.addFilterQuery("listing_status:" + listingStatus);

            queryParamMap.put("fl", "id,address,zip,city,list_price,listing_category,listing_key,listing_status,listing_date,provider_name,provider_url,provider_category,bedroom_count,bathroom_count,property_type,property_subtype,hero_image,living_area,lot_size,year_built,is_star,is_check,longitude,latitude,is_new_house,video_url,data_source");

            queryParamMap.put("start", String.valueOf(start));//记录开始位置

            queryParamMap.put("rows", String.valueOf(pageSize));//查询的行数

            System.err.println("queryParamMap:" + queryParamMap.toString());
            System.err.println("=================================================================");
            System.err.println("filterQuery:" + filterQuery.toString());

            MapSolrParams mapSolrParams = new MapSolrParams(queryParamMap);

            ModifiableSolrParams modifiableSolrParams = new ModifiableSolrParams();

            modifiableSolrParams.add(mapSolrParams);
            modifiableSolrParams.add(filterQuery);

            System.err.println(modifiableSolrParams.toQueryString());

            final QueryResponse response = httpSolrClient.query("listhub", modifiableSolrParams, SolrRequest.METHOD.POST);

            SolrDocumentList documents = response.getResults();
            total = documents.getNumFound();
            System.err.println("数量：" + documents.getNumFound());
            //System.err.println("solr-time--1:" + (System.currentTimeMillis() - time));

            for (SolrDocument solrDocument : documents) {
                ListHubList listHubList = new ListHubList();
                if (solrDocument.get("id") != null) {
                    listHubList.setHouseId(String.valueOf(solrDocument.get("id")));
                }
                if (solrDocument.get("address") != null) {
                    listHubList.setAddress(String.valueOf(solrDocument.get("address")));
                }
                if (solrDocument.get("zip") != null) {
                    listHubList.setZip(String.valueOf(solrDocument.get("zip")));
                }
                if (solrDocument.get("city") != null) {
                    listHubList.setCity(String.valueOf(solrDocument.get("city")));
                }
                if (solrDocument.get("list_price") != null) {
                    listHubList.setListPrice(Double.valueOf(solrDocument.get("list_price").toString()));
                }
                if (solrDocument.get("listing_category") != null) {
                    listHubList.setListingCategory(String.valueOf(solrDocument.get("listing_category")));
                }
                if (solrDocument.get("listing_key") != null) {
                    listHubList.setListingKey(String.valueOf(solrDocument.get("listing_key")));
                }
                if (solrDocument.get("listing_status") != null) {
                    listHubList.setListingStatus(String.valueOf(solrDocument.get("listing_status")));
                }
                if (solrDocument.get("listing_date") != null) {
                    System.err.println("listing_date:" + solrDocument.get("listing_date").toString());
                    String date = solrDocument.get("listing_date").toString();
                    SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK);
                    try {
                        Date d = sdf.parse(date);
                        listHubList.setListingDate(d);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
                if (solrDocument.get("provider_name") != null) {
                    listHubList.setProviderName(String.valueOf(solrDocument.get("provider_name")));
                }
                if (solrDocument.get("provider_url") != null) {
                    listHubList.setProviderUrl(String.valueOf(solrDocument.get("provider_url")));
                }
                if (solrDocument.get("provider_category") != null) {
                    listHubList.setProviderCategory(String.valueOf(solrDocument.get("provider_category")));
                }
                if (solrDocument.get("bedroom_count") != null) {
                    listHubList.setBedroomCount(Integer.valueOf(solrDocument.get("bedroom_count").toString()));
                }
                if (solrDocument.get("bathroom_count") != null) {
                    listHubList.setBathroomCount(Integer.valueOf(solrDocument.get("bathroom_count").toString()));
                }
                if (solrDocument.get("property_type") != null) {
                    listHubList.setPropertyType(String.valueOf(solrDocument.get("property_type").toString()));
                }
                if (solrDocument.get("property_subtype") != null) {
                    listHubList.setPropertySubtype(String.valueOf(solrDocument.get("property_subtype").toString()));
                }
                if (solrDocument.get("hero_image") != null) {
                    listHubList.setHeroImage(String.valueOf(solrDocument.get("hero_image").toString()));
                }
                if (solrDocument.get("living_area") != null) {
                    listHubList.setLivingArea(Double.valueOf(solrDocument.get("living_area").toString()));
                }
                if (solrDocument.get("lot_size") != null) {
                    listHubList.setLotSize(Double.valueOf(solrDocument.get("lot_size").toString()));
                }
                if (solrDocument.get("year_built") != null) {
                    listHubList.setYearBuilt(Integer.valueOf(solrDocument.get("year_built").toString()));
                }
                if (solrDocument.get("is_star") != null) {
                    listHubList.setIsStar(Boolean.valueOf(solrDocument.get("is_star").toString()));
                }
                if (solrDocument.get("is_check") != null) {
                    listHubList.setIsCheck(Boolean.valueOf(solrDocument.get("is_check").toString()));
                }
                if (solrDocument.get("longitude") != null) {
                    listHubList.setLng(Double.valueOf(solrDocument.get("longitude").toString()));
                }
                if (solrDocument.get("latitude") != null) {
                    listHubList.setLat(Double.valueOf(solrDocument.get("latitude").toString()));
                }
                if (solrDocument.get("is_new_house") != null) {
                    listHubList.setIsNewHouse(Boolean.valueOf(solrDocument.get("is_new_house").toString()));
                }

                //1->ListHub;2->SimplyRETS;3->YouHome
                if (solrDocument.get("data_source") != null) {
                    String data_source = solrDocument.get("data_source").toString();
                    if (!StringUtils.isEmpty(data_source)) {
                        Integer key = HouseDataSourceEnum.getEnumByName(data_source).getKey();
                        listHubList.setDataSource(key.toString());
                    }
                }
                lists.add(listHubList);
            }

        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.err.println("solr-time:" + (System.currentTimeMillis() - time));

        PageInfo pageInfo = new PageInfo();
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(total);

        int pages = (int) ((total + pageSize - 1) / pageSize);// (int) Math.ceil((total / pageSize));
        pageInfo.setPages(pages);
        pageInfo.setPageNum(pageNumber);
        pageInfo.setList(lists);
        return pageInfo;
    }

    @Override
    public PageInfo<ListHubList> searchByBean(String action, String keyword, Integer pageNumber, Integer pageSize,
                                              String type, Integer beds, Integer baths, Integer year,
                                              Double minSize, Double maxSize, Double minPrice, Double maxPrice,
                                              String filed, String direction, Boolean isStar, Boolean isCheck,
                                              Double minX, Double maxX, Double minY, Double maxY, Long companyId, Boolean isNewHouse, String listingStatus) {
        if (StringUtils.isEmpty(pageNumber) || pageNumber < 1) {
            pageNumber = 1;
        }
        if (StringUtils.isEmpty(pageSize) || pageSize < 10) {
            pageSize = 10;
        }
        String[] types = new String[]{};
        if (!StringUtils.isEmpty(type)) {
            types = type.split(",");
        }
        long total = 0;

        List<ListHubList> lists = new ArrayList<>();
        long time = System.currentTimeMillis();
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrConfig.getHost())
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();

            final Map<String, String> queryParamMap = new HashMap<>();
            SolrQuery filterQuery = new SolrQuery();

            Integer start = (pageNumber - 1) * pageSize;

            if (!StringUtils.isEmpty(action)) {
                if (action.equals("zip")) {
                    queryParamMap.put("q", "zip:" + keyword);
                }
                if (action.equals("city")) {
                    List<String> zips;
                    if (StringUtils.isHotCity(keyword)) {
                        String zipCodes = hotCityMapper.selectZipsByEnName(keyword); //查找热门城市自定义邮编
                        zips = Arrays.asList(zipCodes.split(","));
                    } else {
                        zips = zipMapper.selectZipsByCity(keyword); //查找city 所有邮编
                    }
                    //优先按邮编查询，如果按城市查询出的zips 为空直接按城市查询
                    if (zips != null && zips.size() > 0) {
                        System.err.println("=====按邮编查询====邮编数量：" + zips.size() + "==================");
                        List<String> items = new ArrayList<>();
                        for (String zip : zips) {
                            items.add("zip:" + zip);
                        }
                        queryParamMap.put("q", "*:*");
                        filterQuery.addFilterQuery(String.join(" OR ", items));
                    } else {
                        System.err.println("=====直接按城市查询====城市：" + keyword + "==================");
                        queryParamMap.put("q", "city:" + keyword);
                    }
                }
                if (action.equals("address")) {
                    queryParamMap.put("q", "address:" + keyword);
                }
            } else {
                queryParamMap.put("q", "*:*");
            }

            if (types.length > 0) {
                List<String> property_subtypes = new ArrayList<>();
                for (String str : types) {
                    property_subtypes.add("property_subtype:" + str);
                }
                filterQuery.addFilterQuery(String.join(" OR ", property_subtypes));
            }

            if (!StringUtils.isEmpty(beds) && beds > 0) {
                filterQuery.addFilterQuery("bedroom_count:[ " + beds + " TO *]");
            }
            if (!StringUtils.isEmpty(baths) && baths > 0) {
                filterQuery.addFilterQuery("bathroom_count:[ " + baths + " TO *]");
            }
            if (!StringUtils.isEmpty(year) && year > 0) {
                filterQuery.addFilterQuery("year_built:[ " + year + " TO *]");
            }
            //面积
            if (!StringUtils.isEmpty(minSize) && !StringUtils.isEmpty(maxSize) && minSize > 0 && maxSize > 0) {
                filterQuery.addFilterQuery("living_area:[ " + minSize + " TO " + maxSize + "]");
            } else if (!StringUtils.isEmpty(minSize) && StringUtils.isEmpty(maxSize) && minSize > 0) {
                filterQuery.addFilterQuery("living_area:[ " + minSize + " TO *]");
            } else if (!StringUtils.isEmpty(maxSize) && StringUtils.isEmpty(minSize) && maxSize > 0) {
                filterQuery.addFilterQuery("living_area:[ * TO " + maxSize + "]");
            }
            //价格
            if (!StringUtils.isEmpty(minPrice) && !StringUtils.isEmpty(maxPrice) && minPrice > 0 && maxPrice > 0) {
                filterQuery.addFilterQuery("list_price:[ " + minPrice + " TO " + maxPrice + "]");
            } else if (!StringUtils.isEmpty(minPrice) && StringUtils.isEmpty(maxPrice) && minPrice > 0) {
                filterQuery.addFilterQuery("list_price:[ " + minPrice + " TO *]");
            } else if (!StringUtils.isEmpty(maxPrice) && StringUtils.isEmpty(minPrice) && maxPrice > 0) {
                filterQuery.addFilterQuery("list_price:[ * TO " + maxPrice + "]");
            }

            if (!StringUtils.isEmpty(maxX) && !StringUtils.isEmpty(maxY) && !StringUtils.isEmpty(minX) && !StringUtils.isEmpty(minY)) {
                //经度 longitude(Y) and 纬度latitude (X)
                //左上角坐标
                Point p1 = new Point(minX, maxY);
                //右上角坐标
                Point p2 = new Point(maxX, maxY);
                //右下角坐标
                Point p3 = new Point(maxX, minY);
                //左下角坐标
                Point p4 = new Point(minX, minY);

                List<String> points = new ArrayList<>();

                points.add(minY + " " + maxX);
                points.add(maxY + " " + maxX);
                points.add(maxY + " " + minX);
                points.add(minY + " " + minX);
                points.add(minY + " " + maxX);
                String polygon = String.join(",", points);
                System.err.println(polygon);
                filterQuery.addFilterQuery("{!field f=point}Intersects(POLYGON((" + polygon + ")))"); //距离过滤函数
            }

            if (!StringUtils.isEmpty(isStar)) {
                filterQuery.addFilterQuery("is_star:" + isStar);
            }

            if (!StringUtils.isEmpty(isCheck)) {
                filterQuery.addFilterQuery("is_check:" + isCheck);
            }

            if (!StringUtils.isEmpty(companyId)) {
                filterQuery.addFilterQuery("company_id:" + companyId);
            }

            if (!StringUtils.isEmpty(isNewHouse)) {
                filterQuery.addFilterQuery("is_new_house:" + isNewHouse);
            }

            //排序
            if (!StringUtils.isEmpty(filed) && !StringUtils.isEmpty(direction)) {
                queryParamMap.put("sort", StringUtils.transitionOrderBy(filed) + " " + direction);
            } else {
                filterQuery.setSort("year_built", SolrQuery.ORDER.desc);
            }

            filterQuery.addFilterQuery("enabled:true");
            filterQuery.addFilterQuery("listing_status:" + listingStatus);

            queryParamMap.put("fl", "id,address,zip,city,list_price,listing_category,listing_key,listing_status,listing_date,provider_name,provider_url,provider_category,bedroom_count,bathroom_count,property_type,property_subtype,hero_image,living_area,lot_size,year_built,is_star,is_check,longitude,latitude,is_new_house,video_url,data_source");

            queryParamMap.put("start", String.valueOf(start));//记录开始位置

            queryParamMap.put("rows", String.valueOf(pageSize));//查询的行数

            System.err.println("queryParamMap:" + queryParamMap.toString());
            System.err.println("=================================================================");
            System.err.println("filterQuery:" + filterQuery.toString());

            MapSolrParams mapSolrParams = new MapSolrParams(queryParamMap);

            ModifiableSolrParams modifiableSolrParams = new ModifiableSolrParams();

            modifiableSolrParams.add(mapSolrParams);
            modifiableSolrParams.add(filterQuery);

            System.err.println(modifiableSolrParams.toQueryString());

            final QueryResponse response = httpSolrClient.query("listhub", modifiableSolrParams, SolrRequest.METHOD.POST);

            SolrDocumentList documents = response.getResults();
            total = documents.getNumFound();
            System.err.println("数量：" + documents.getNumFound());
            //System.err.println("solr-time--1:" + (System.currentTimeMillis() - time));

            for (SolrDocument solrDocument : documents) {
                //System.err.println(solrDocument);
                //HouseListResult listHubList = SolrUtils.solrDocumentToPojo(solrDocument, HouseListResult.class);
                ListHubList listHubList = new ListHubList();
                if (solrDocument.get("id") != null) {
                    listHubList.setHouseId(String.valueOf(solrDocument.get("id")));
                }
                if (solrDocument.get("address") != null) {
                    listHubList.setAddress(String.valueOf(solrDocument.get("address")));
                }
                if (solrDocument.get("zip") != null) {
                    listHubList.setZip(String.valueOf(solrDocument.get("zip")));
                }
                if (solrDocument.get("city") != null) {
                    listHubList.setCity(String.valueOf(solrDocument.get("city")));
                }
                if (solrDocument.get("list_price") != null) {
                    listHubList.setListPrice(Double.valueOf(solrDocument.get("list_price").toString()));
                }
                if (solrDocument.get("listing_category") != null) {
                    listHubList.setListingCategory(String.valueOf(solrDocument.get("listing_category")));
                }
                if (solrDocument.get("listing_key") != null) {
                    listHubList.setListingKey(String.valueOf(solrDocument.get("listing_key")));
                }
                if (solrDocument.get("listing_status") != null) {
                    listHubList.setListingStatus(String.valueOf(solrDocument.get("listing_status")));
                }
                if (solrDocument.get("listing_date") != null) {
                    System.err.println("listing_date:" + solrDocument.get("listing_date").toString());
                    String date = solrDocument.get("listing_date").toString();
                    SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK);
                    try {
                        Date d = sdf.parse(date);
                        listHubList.setListingDate(d);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
                if (solrDocument.get("provider_name") != null) {
                    listHubList.setProviderName(String.valueOf(solrDocument.get("provider_name")));
                }
                if (solrDocument.get("provider_url") != null) {
                    listHubList.setProviderUrl(String.valueOf(solrDocument.get("provider_url")));
                }
                if (solrDocument.get("provider_category") != null) {
                    listHubList.setProviderCategory(String.valueOf(solrDocument.get("provider_category")));
                }
                if (solrDocument.get("bedroom_count") != null) {
                    listHubList.setBedroomCount(Integer.valueOf(solrDocument.get("bedroom_count").toString()));
                }
                if (solrDocument.get("bathroom_count") != null) {
                    listHubList.setBathroomCount(Integer.valueOf(solrDocument.get("bathroom_count").toString()));
                }
                if (solrDocument.get("property_type") != null) {
                    listHubList.setPropertyType(String.valueOf(solrDocument.get("property_type").toString()));
                }
                if (solrDocument.get("property_subtype") != null) {
                    listHubList.setPropertySubtype(String.valueOf(solrDocument.get("property_subtype").toString()));
                }
                if (solrDocument.get("hero_image") != null) {
                    listHubList.setHeroImage(String.valueOf(solrDocument.get("hero_image").toString()));
                }
                if (solrDocument.get("living_area") != null) {
                    listHubList.setLivingArea(Double.valueOf(solrDocument.get("living_area").toString()));
                }
                if (solrDocument.get("lot_size") != null) {
                    listHubList.setLotSize(Double.valueOf(solrDocument.get("lot_size").toString()));
                }
                if (solrDocument.get("year_built") != null) {
                    listHubList.setYearBuilt(Integer.valueOf(solrDocument.get("year_built").toString()));
                }
                if (solrDocument.get("is_star") != null) {
                    listHubList.setIsStar(Boolean.valueOf(solrDocument.get("is_star").toString()));
                }
                if (solrDocument.get("is_check") != null) {
                    listHubList.setIsCheck(Boolean.valueOf(solrDocument.get("is_check").toString()));
                }
                if (solrDocument.get("longitude") != null) {
                    listHubList.setLng(Double.valueOf(solrDocument.get("longitude").toString()));
                }
                if (solrDocument.get("latitude") != null) {
                    listHubList.setLat(Double.valueOf(solrDocument.get("latitude").toString()));
                }
                if (solrDocument.get("is_new_house") != null) {
                    listHubList.setIsNewHouse(Boolean.valueOf(solrDocument.get("is_new_house").toString()));
                }

                //1->ListHub;2->SimplyRETS;3->YouHome
                if (solrDocument.get("data_source") != null) {
                    String data_source = solrDocument.get("data_source").toString();
                    if (!StringUtils.isEmpty(data_source)) {
                        Integer key = HouseDataSourceEnum.getEnumByName(data_source).getKey();
                        listHubList.setDataSource(key.toString());
                    }
                }

                lists.add(listHubList);
            }

        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.err.println("solr-time:" + (System.currentTimeMillis() - time));

        PageInfo pageInfo = new PageInfo();
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(total);

        int pages = (int) ((total + pageSize - 1) / pageSize);// (int) Math.ceil((total / pageSize));
        pageInfo.setPages(pages);
        pageInfo.setPageNum(pageNumber);

        pageInfo.setList(lists);

        return pageInfo;
    }

    @Override
    public List<HouseMap> searchMapByBean(String action, String keyword,

                                          String type, Integer beds, Integer baths,
                                          Integer year,
                                          Double minSize, Double maxSize,
                                          Double minPrice, Double maxPrice,

                                          String filed, String direction,

                                          Boolean isStar, Boolean isCheck,
                                          Double minX, Double maxX, Double minY, Double maxY,
                                          Long companyId) {

        String[] types = new String[]{};
        if (!StringUtils.isEmpty(type)) {
            types = type.split(",");
        }
        long total = 0;

        List<HouseMap> lists = new ArrayList<>();
        long time = System.currentTimeMillis();
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrConfig.getHost())
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();

            //final Map<String, String> queryParamMap = new HashMap<>();
            SolrQuery filterQuery = new SolrQuery();

            if (!StringUtils.isEmpty(action)) {
                if (action.equals("zip")) {
                    //queryParamMap.put("q", "zip:" + keyword);
                    filterQuery.setQuery("zip:" + keyword);
                }
                if (action.equals("city")) {
                    List<String> items = new ArrayList<>();

                    List<String> zips = new ArrayList<>();
                    if (keyword.equals("San Francisco") ||
                            keyword.equals("Los Angeles") ||
                            keyword.equals("New York") ||
                            keyword.equals("Seattle") ||
                            keyword.equals("Atlanta") ||
                            keyword.equals("Boston") ||
                            keyword.equals("New Jersey") ||
                            keyword.equals("Houston") ||
                            keyword.equals("San Diago") ||
                            keyword.equals("Orlando")
                            ) {
                        String zipcodes = hotCityMapper.selectZipsByEnName(keyword);
                        zips = Arrays.asList(zipcodes.split(","));
                    } else {
                        zips = zipMapper.selectZipsByCity(keyword);
                    }

                    //System.err.println(zips.toString());
                    for (String zip : zips) {
                        items.add("zip:" + zip);
                    }
                    //queryParamMap.put("q", "*:*");
                    filterQuery.setQuery("*:*");
                    //System.err.println(String.join(" OR ", items));
                    filterQuery.addFilterQuery(String.join(" OR ", items));
                    //queryParamMap.put("q", "city:" + keyword);
                }
                if (action.equals("address")) {
                    //queryParamMap.put("q", "address:" + keyword);
                    filterQuery.setQuery("address:" + keyword);
                }
            } else {
                //queryParamMap.put("q", "*:*");
                filterQuery.setQuery("*:*");
            }


            if (types.length > 0) {
                List<String> property_subtypes = new ArrayList<>();
                for (String str : types) {
                    property_subtypes.add("property_subtype:" + str);
                }
                filterQuery.addFilterQuery(String.join(" OR ", property_subtypes));
            }

            if (!StringUtils.isEmpty(beds) && beds > 0) {
                filterQuery.addFilterQuery("bedroom_count:[ " + beds + " TO *]");
            }
            if (!StringUtils.isEmpty(baths) && baths > 0) {
                filterQuery.addFilterQuery("bathroom_count:[ " + baths + " TO *]");
            }
            if (!StringUtils.isEmpty(year) && year > 0) {
                filterQuery.addFilterQuery("year_built:[ " + year + " TO *]");
            }
            //面积
            if (!StringUtils.isEmpty(minSize) && !StringUtils.isEmpty(maxSize) && minSize > 0 && maxSize > 0) {
                filterQuery.addFilterQuery("living_area:[ " + minSize + " TO " + maxSize + "]");
            } else if (!StringUtils.isEmpty(minSize) && StringUtils.isEmpty(maxSize) && minSize > 0) {
                filterQuery.addFilterQuery("living_area:[ " + minSize + " TO *]");
            } else if (!StringUtils.isEmpty(maxSize) && StringUtils.isEmpty(minSize) && maxSize > 0) {
                filterQuery.addFilterQuery("living_area:[ * TO " + maxSize + "]");
            }
            //价格
            if (!StringUtils.isEmpty(minPrice) && !StringUtils.isEmpty(maxPrice) && minPrice > 0 && maxPrice > 0) {
                filterQuery.addFilterQuery("list_price:[ " + minPrice + " TO " + maxPrice + "]");
            } else if (!StringUtils.isEmpty(minPrice) && StringUtils.isEmpty(maxPrice) && minPrice > 0) {
                filterQuery.addFilterQuery("list_price:[ " + minPrice + " TO *]");
            } else if (!StringUtils.isEmpty(maxPrice) && StringUtils.isEmpty(minPrice) && maxPrice > 0) {
                filterQuery.addFilterQuery("list_price:[ * TO " + maxPrice + "]");
            }

            if (!StringUtils.isEmpty(maxX) && !StringUtils.isEmpty(maxY) && !StringUtils.isEmpty(minX) && !StringUtils.isEmpty(minY)) {
                //经度 longitude(Y) and 纬度latitude (X)
                List<String> points = new ArrayList<>();

                points.add(minY + " " + maxX);
                points.add(maxY + " " + maxX);
                points.add(maxY + " " + minX);
                points.add(minY + " " + minX);
                points.add(minY + " " + maxX);

                String polygon = String.join(",", points);

                //System.err.println(polygon);

                filterQuery.addFilterQuery("{!field f=point}Intersects(POLYGON((" + polygon + ")))"); //距离过滤函数
            }

            if (!StringUtils.isEmpty(isStar)) {
                filterQuery.addFilterQuery("is_star:" + isStar);
            }

            if (!StringUtils.isEmpty(isCheck)) {
                filterQuery.addFilterQuery("is_check:" + isCheck);
            }


            filterQuery.addFilterQuery("enabled:true");
            filterQuery.addFilterQuery("longitude:[-180 TO 180]"); //经度
            filterQuery.addFilterQuery("latitude:[-90 TO 90]"); //纬度
            filterQuery.addFilterQuery("listing_status:Active");

            filterQuery.setFields("id", "list_price", "latitude", "longitude");

            filterQuery.setStart(0);

            filterQuery.setRows(100000);

            ModifiableSolrParams modifiableSolrParams = new ModifiableSolrParams();

            modifiableSolrParams.add(filterQuery);

            //System.err.println(modifiableSolrParams.toQueryString());

            final QueryResponse response = httpSolrClient.query("listhub", modifiableSolrParams, SolrRequest.METHOD.POST);


            SolrDocumentList documents = response.getResults();
            total = documents.getNumFound();
            System.err.println("数量：" + total);
            //System.err.println("solr-time--1:" + (System.currentTimeMillis() - time));

            for (SolrDocument solrDocument : documents) {
                //System.err.println(solrDocument);
                //HouseListResult listHubList = SolrUtils.solrDocumentToPojo(solrDocument, HouseListResult.class);
                HouseMap listHubList = new HouseMap();
                if (solrDocument.get("id") != null) {
                    listHubList.setHouseId(String.valueOf(solrDocument.get("id")));
                }

                if (solrDocument.get("list_price") != null) {
                    listHubList.setListPrice(Double.valueOf(solrDocument.get("list_price").toString()));
                }

                if (solrDocument.get("latitude") != null) {
                    listHubList.setLatitude(Double.valueOf(solrDocument.get("latitude").toString()));
                }
                if (solrDocument.get("longitude") != null) {
                    listHubList.setLongitude(Double.valueOf(solrDocument.get("longitude").toString()));
                }

                lists.add(listHubList);
            }

        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.err.println("solr-time:" + (System.currentTimeMillis() - time));

        return lists;
    }

    @Override
    public List<HouseMapShort> searchMapShortByBean(String action, String keyword,

                                                    String type, Integer beds, Integer baths,
                                                    Integer year,
                                                    Double minSize, Double maxSize,
                                                    Double minPrice, Double maxPrice,

                                                    String filed, String direction,

                                                    Boolean isStar, Boolean isCheck,
                                                    Double minX, Double maxX, Double minY, Double maxY,
                                                    Long companyId) {

        String[] types = new String[]{};
        if (!StringUtils.isEmpty(type)) {
            types = type.split(",");
        }
        long total = 0;

        List<HouseMapShort> lists = new ArrayList<>();
        long time = System.currentTimeMillis();
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrConfig.getHost())
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();

            //final Map<String, String> queryParamMap = new HashMap<>();
            SolrQuery filterQuery = new SolrQuery();

            if (!StringUtils.isEmpty(action)) {
                if (action.equals("zip")) {
                    //queryParamMap.put("q", "zip:" + keyword);
                    filterQuery.setQuery("zip:" + keyword);
                }
                if (action.equals("city")) {
                    List<String> items = new ArrayList<>();

                    List<String> zips = new ArrayList<>();
                    if (keyword.equals("San Francisco") ||
                            keyword.equals("Los Angeles") ||
                            keyword.equals("New York") ||
                            keyword.equals("Seattle") ||
                            keyword.equals("Atlanta") ||
                            keyword.equals("Boston") ||
                            keyword.equals("New Jersey") ||
                            keyword.equals("Houston") ||
                            keyword.equals("San Diago") ||
                            keyword.equals("Orlando")
                            ) {
                        String zipcodes = hotCityMapper.selectZipsByEnName(keyword);
                        zips = Arrays.asList(zipcodes.split(","));
                    } else {
                        zips = zipMapper.selectZipsByCity(keyword);
                    }

                    //System.err.println(zips.toString());
                    for (String zip : zips) {
                        items.add("zip:" + zip);
                    }
                    //queryParamMap.put("q", "*:*");
                    filterQuery.setQuery("*:*");
                    //System.err.println(String.join(" OR ", items));
                    filterQuery.addFilterQuery(String.join(" OR ", items));
                    //queryParamMap.put("q", "city:" + keyword);
                }
                if (action.equals("address")) {
                    //queryParamMap.put("q", "address:" + keyword);
                    filterQuery.setQuery("address:" + keyword);
                }
            } else {
                //queryParamMap.put("q", "*:*");
                filterQuery.setQuery("*:*");
            }


            if (types.length > 0) {
                List<String> property_subtypes = new ArrayList<>();
                for (String str : types) {
                    property_subtypes.add("property_subtype:" + str);
                }
                filterQuery.addFilterQuery(String.join(" OR ", property_subtypes));
            }

            if (!StringUtils.isEmpty(beds) && beds > 0) {
                filterQuery.addFilterQuery("bedroom_count:[ " + beds + " TO *]");
            }
            if (!StringUtils.isEmpty(baths) && baths > 0) {
                filterQuery.addFilterQuery("bathroom_count:[ " + baths + " TO *]");
            }
            if (!StringUtils.isEmpty(year) && year > 0) {
                filterQuery.addFilterQuery("year_built:[ " + year + " TO *]");
            }
            //面积
            if (!StringUtils.isEmpty(minSize) && !StringUtils.isEmpty(maxSize) && minSize > 0 && maxSize > 0) {
                filterQuery.addFilterQuery("living_area:[ " + minSize + " TO " + maxSize + "]");
            } else if (!StringUtils.isEmpty(minSize) && StringUtils.isEmpty(maxSize) && minSize > 0) {
                filterQuery.addFilterQuery("living_area:[ " + minSize + " TO *]");
            } else if (!StringUtils.isEmpty(maxSize) && StringUtils.isEmpty(minSize) && maxSize > 0) {
                filterQuery.addFilterQuery("living_area:[ * TO " + maxSize + "]");
            }
            //价格
            if (!StringUtils.isEmpty(minPrice) && !StringUtils.isEmpty(maxPrice) && minPrice > 0 && maxPrice > 0) {
                filterQuery.addFilterQuery("list_price:[ " + minPrice + " TO " + maxPrice + "]");
            } else if (!StringUtils.isEmpty(minPrice) && StringUtils.isEmpty(maxPrice) && minPrice > 0) {
                filterQuery.addFilterQuery("list_price:[ " + minPrice + " TO *]");
            } else if (!StringUtils.isEmpty(maxPrice) && StringUtils.isEmpty(minPrice) && maxPrice > 0) {
                filterQuery.addFilterQuery("list_price:[ * TO " + maxPrice + "]");
            }

            if (!StringUtils.isEmpty(maxX) && !StringUtils.isEmpty(maxY) && !StringUtils.isEmpty(minX) && !StringUtils.isEmpty(minY)) {
                //经度 longitude(Y) and 纬度latitude (X)
                List<String> points = new ArrayList<>();

                points.add(minY + " " + maxX);
                points.add(maxY + " " + maxX);
                points.add(maxY + " " + minX);
                points.add(minY + " " + minX);
                points.add(minY + " " + maxX);

                String polygon = String.join(",", points);

                System.err.println(polygon);

                filterQuery.addFilterQuery("{!field f=point}Intersects(POLYGON((" + polygon + ")))"); //距离过滤函数
            }

            if (!StringUtils.isEmpty(isStar)) {
                filterQuery.addFilterQuery("is_star:" + isStar);
            }

            if (!StringUtils.isEmpty(isCheck)) {
                filterQuery.addFilterQuery("is_check:" + isCheck);
            }


            filterQuery.addFilterQuery("enabled:true");
            filterQuery.addFilterQuery("longitude:[-180 TO 180]"); //经度
            filterQuery.addFilterQuery("latitude:[-90 TO 90]"); //纬度
            filterQuery.addFilterQuery("listing_status:Active");

            filterQuery.setFields("id", "list_price", "latitude", "longitude");

            filterQuery.setStart(0);

            filterQuery.setRows(100000);

            ModifiableSolrParams modifiableSolrParams = new ModifiableSolrParams();

            modifiableSolrParams.add(filterQuery);

            System.err.println(modifiableSolrParams.toQueryString());

            final QueryResponse response = httpSolrClient.query("listhub", modifiableSolrParams, SolrRequest.METHOD.POST);


            SolrDocumentList documents = response.getResults();
            total = documents.getNumFound();
            System.err.println("数量：" + total);
            //System.err.println("solr-time--1:" + (System.currentTimeMillis() - time));

            for (SolrDocument solrDocument : documents) {
                //System.err.println(solrDocument);
                //HouseListResult listHubList = SolrUtils.solrDocumentToPojo(solrDocument, HouseListResult.class);

                if (solrDocument.get("latitude") != null && solrDocument.get("longitude") != null) {
                    HouseMapShort listHubList = new HouseMapShort();
                    if (solrDocument.get("id") != null) {
                        listHubList.setI(String.valueOf(solrDocument.get("id")));
                    }

                    if (solrDocument.get("list_price") != null) {
                        listHubList.setP(Double.valueOf(solrDocument.get("list_price").toString()));
                    }
                    Double latitude = Double.valueOf(solrDocument.get("latitude").toString());
                    Double longitude = Double.valueOf(solrDocument.get("longitude").toString());
                    listHubList.setT(latitude);
                    listHubList.setG(longitude);

                    //判断坐标点是否在美国境内 大致范围
                    boolean usaPolygonContainsPoint = geoService.isUSAPolygonContainsPoint(longitude, latitude);
                    if (listHubList.getG() != 0 && listHubList.getT() != 0 && usaPolygonContainsPoint) {
                        lists.add(listHubList);
                    }
                }
            }

        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.err.println("solr-time:" + (System.currentTimeMillis() - time));

        return lists;
    }

    @Override
    public int deleteHouseIndex(String houseId) {
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrConfig.getHost() + "/listhub")
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();
            System.err.println(httpSolrClient.getBaseURL());
            UpdateResponse updateResponse = httpSolrClient.deleteById(houseId);
            httpSolrClient.commit();

            if (updateResponse.getStatus() == 0) {
                return 1;
            }
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return 0;
    }

    @Override
    public int saveHouseIndex(String houseId) {
        ListHub listHub = listHubService.selectByPrimaryKey(houseId);
        return saveHouseIndex(listHub);
    }

    @Override
    public int saveHouseIndex(ListHub record) {
        System.err.println(record.toString());
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrConfig.getHost() + "/listhub")
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();
            System.err.println(httpSolrClient.getBaseURL());

            String point = null;
            if (!StringUtils.isEmpty(record.getLongitude()) && !StringUtils.isEmpty(record.getLatitude())) {
                point = record.getLongitude() + " " + record.getLatitude();
            }

            SolrInputDocument doc = new SolrInputDocument();


            doc.addField("id", record.getHouseId());
            doc.addField("address", record.getAddress());
            doc.addField("county", record.getCounty());
            doc.addField("city", record.getCity());
            doc.addField("province", record.getProvince());
            doc.addField("zip", record.getZip());
            doc.addField("list_price", record.getListPrice());
            doc.addField("list_price_low", record.getListPriceLow());
            doc.addField("listing_category", record.getListingCategory());
            doc.addField("listing_key", record.getListingKey());
            doc.addField("listing_status", record.getListingStatus());
            doc.addField("listing_description", record.getListingDescription());
            doc.addField("listing_date", record.getListingDate());
            doc.addField("listing_title", record.getListingTitle());
            doc.addField("provider_name", record.getProviderName());
            doc.addField("provider_url", record.getProviderUrl());
            doc.addField("provider_category", record.getProviderUrl());
            doc.addField("lead_routing_email", record.getLeadRoutingEmail());
            doc.addField("bedroom_count", record.getBedroomCount());
            doc.addField("bathroom_count", record.getBathroomCount());

            doc.addField("full_bathroom_count", record.getFullBathroomCount());
            doc.addField("three_quarter_bathroom_count", record.getThreeQuarterBathroomCount());
            doc.addField("half_bathroom_count", record.getHalfBathroomCount());
            doc.addField("one_quarter_bathroom_count", record.getOneQuarterBathroomCount());

            doc.addField("property_type", record.getPropertyType());
            doc.addField("property_subtype", record.getPropertySubtype());

            doc.addField("permit_address_on_internet", record.getPermitAddressOnInternet());
            doc.addField("permit_address_display", record.getPermitAddressDisplay());
            doc.addField("permit_automated_valuation", record.getPermitAutomatedValuation());
            doc.addField("permit_consumer_comment", record.getPermitConsumerComment());
            doc.addField("permit_address_disclose", record.getPermitAddressDisclose());

            doc.addField("hero_image", record.getHeroImage());
            doc.addField("mls_id", record.getMlsId());
            doc.addField("mls_name", record.getMlsName());
            doc.addField("mls_number", record.getMlsNumber());
            doc.addField("living_area", record.getLivingArea());
            doc.addField("lot_size", record.getLotSize());
            doc.addField("year_built", record.getYearBuilt());
            doc.addField("foreclosure_status", record.getForecastRent());
            doc.addField("builder_name", record.getBuilderName());
            doc.addField("latitude", record.getLatitude());
            doc.addField("longitude", record.getLongitude());
            doc.addField("parcel_id", record.getParcelId());


            doc.addField("modification_timestamp", record.getModificationTimestamp());
            doc.addField("disclaimer", record.getDisclaimer());


            doc.addField("create_time", record.getCreateTime());
            doc.addField("update_time", record.getUpdateTime());

            doc.addField("enabled", record.getEnabled());

            doc.addField("page_view", record.getPageView());
            doc.addField("collection", record.getCollection());

            doc.addField("company_id", record.getCompanyId());
            doc.addField("counselor_id", record.getCounselorId());
            doc.addField("is_star", record.getIsStar());
            doc.addField("is_check", record.getIsCheck());


            doc.addField("update_batch", record.getUpdateBatch());

            doc.addField("geocoding_status", record.getGeocodingStatus());
            doc.addField("geocoding_source", record.getGeocodingSource());

            doc.addField("data_source", record.getDataSource());
            doc.addField("updateTime", record.getUpdateTime());

            doc.addField("point", point);
            doc.addField("is_new_house", record.getIsNewHouse());

            UpdateResponse updateResponse = httpSolrClient.add(doc);
            httpSolrClient.commit();

            if (updateResponse.getStatus() == 0) {
                log.info(record.getHouseId() + "==>>更新视频索引成功");
                return 1;
            } else {
                log.info(record.getHouseId() + "==>>更新视频索引失败");
            }
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return 0;
    }

    @Override
    public PageInfo<ListHubList> searchByDTOSearch(ParamHouseSearch record) throws CustomException {

        long btime = System.currentTimeMillis();
        String action = record.getAction();
        String keyword = record.getKeyword();
        validateSearchType(action, keyword);
        Boolean isCheck = null;
        //查询自有房源
        Long companyId = null;
        if (!StringUtils.isEmpty(record.getIsOwn()) && record.getIsOwn()) {
            BUser currentUser = bUserService.getCurrentUser();
            if (currentUser != null) {
                companyId = bCompanyService.selectCompanyIdByUserId(currentUser.getUserId());
                if (companyId == null) {
                    throw new CustomException(ResultCode.DO_NOT_HAVE_PERMISSION);
                }
            }
        }

        PageInfo<ListHubList> listHubLists = searchByBean(
                action, keyword, record.getPage(), record.getPageSize(), record.getType(), record.getBeds(), record.getBaths(), record.getYear(),
                record.getMinSize(), record.getMaxSize(), record.getMinPrice(), record.getMaxPrice(), record.getFiled(), record.getDirection(), record.getIsStar(),
                isCheck, record.getMinX(), record.getMaxX(), record.getMinY(), record.getMaxY(), companyId, record.getIsNewHouse(), record.getListingStatus());

        if (listHubLists.getList() != null && listHubLists.getList().size() > 0) {

            if (!StringUtils.isEmpty(record.getIsShowShareGroup()) && record.getIsShowShareGroup()) {
                BUser currentUser = bUserService.getCurrentUser();
                if (currentUser == null) {
                    throw new CustomException(ResultCode.EXPIRED_LOGIN);
                }
                BCounselor bCounselor = bCounselorService.selectByUserId(currentUser.getUserId());
                if (bCounselor == null) {
                    throw new CustomException(ResultCode.NO_DATA_WAS_FOUND);
                }
                Long counselorId = bCounselor.getCounselorId();
                if (!StringUtils.isEmpty(counselorId) && counselorId > 0) {
                    for (ListHubList listHub : listHubLists.getList()) {
                        String houseId = listHub.getHouseId();
                        List<String> shareGroupNames = bShareGroupService.selectShareGroupNameByHouseIdAndCounselorId(counselorId, houseId);
                        listHub.setShareGroupNames(shareGroupNames);
                    }
                }
            }
        }

        long etime = System.currentTimeMillis();

        System.err.println("执行时间：" + (etime - btime) + "ms");

        return listHubLists;
    }

    @Override
    public Object associateSearch(String action, String keyword) throws CustomException {
        if (keyword.length() < 3) {
            throw new CustomException(ResultCode.ERROR_KEYWORD_LENGTH_THREE);
        }
        if (action.equalsIgnoreCase("zip")) {
            List<AssociateZip> list = associateSearchByZip(keyword);
            return list;
        } else if (action.equalsIgnoreCase("city")) {
            List<AssociateCity> list = associateSearchByCity(keyword);
            return list;
        } else if (action.equalsIgnoreCase("address")) {
            List<AssociateAddress> list = associateSearchByAddress(keyword);
            return list;
        }
        return null;
    }

    @Override
    public List<HouseMapShort> searchMapShortByBean(ParamHouseMapSearch record) throws CustomException {

        long btime = System.currentTimeMillis();
        String action = record.getAction();
        String keyword = record.getKeyword();
        validateSearchType(action, keyword);

        List<HouseMapShort> list = searchMapShortByBean(action, keyword, record.getType(), record.getBeds(), record.getBaths(), record.getYear(), record.getMinSize(), record.getMaxSize(), record.getMinPrice(), record.getMaxPrice(), record.getFiled(), record.getDirection(), null, null, record.getMinX(), record.getMaxX(), record.getMinY(), record.getMaxY(), null);
        long etime = System.currentTimeMillis();
        System.err.println("执行时间：" + (etime - btime) + "ms");
        return list;
    }

    @Override
    public List<HouseMap> searchMapByBean(ParamHouseMapSearch record) throws CustomException {
        long btime = System.currentTimeMillis();
        String action = record.getAction();
        String keyword = record.getKeyword();
        validateSearchType(action, keyword);
        List<HouseMap> list = searchMapByBean(action, keyword, record.getType(), record.getBeds(), record.getBaths(), record.getYear(), record.getMinSize(), record.getMaxSize(), record.getMinPrice(), record.getMaxPrice(), record.getFiled(), record.getDirection(), null, null, record.getMinX(), record.getMaxX(), record.getMinY(), record.getMaxY(), null);
        long etime = System.currentTimeMillis();
        System.err.println("执行时间：" + (etime - btime) + "ms");
        return list;
    }

    @Override
    public AssociateResult associateSearch(String keyword) throws CustomException {
        if (StringUtils.isEmpty(keyword)) {
            throw new CustomException(ResultCode.ERROR_PARAMETER);
        }
        if (keyword.length() < 3) {
            throw new CustomException(ResultCode.ERROR_KEYWORD_LENGTH_THREE);
        }

        List<AssociateAddress> associateAddresses = associateSearchByAddress(keyword);
        List<AssociateCity> associateCities = associateSearchByCity(keyword);
        List<AssociateZip> associateZips = associateSearchByZip(keyword);

        AssociateResult associate = new AssociateResult();
        associate.setCity(associateCities);
        associate.setZip(associateZips);
        associate.setAddress(associateAddresses);
        return associate;
    }

    @Override
    public PageInfo<ListHubList> searchByBean(ParamHouseSearch record) throws CustomException {
        validateSearchType(record.getAction(), record.getKeyword());

        return searchByBean(
                record.getAction(), record.getKeyword(), record.getPage(), record.getPageSize(), record.getType(),
                record.getBeds(), record.getBaths(), record.getYear(), record.getMinSize(), record.getMaxSize(),
                record.getMinPrice(), record.getMaxPrice(), record.getFiled(), record.getDirection(),
                record.getIsStar(), record.getIsCheck(), record.getMinX(), record.getMaxX(), record.getMinY(),
                record.getMaxY(), record.getCompanyId(), null, null);

    }

    @Override
    public List<InterestPointResult> selectPoiByCoordinateAndDist(Double lat, Double lng, Double distance, Integer count) {
        if(org.springframework.util.StringUtils.isEmpty(count)){
            count = 500;
        }
        String point = lng + " " + lat;

        List<InterestPointResult> list = new ArrayList<>();
        SolrDocumentList documents = null;
        long time = System.currentTimeMillis();
        try {
            HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrHost)
                    .withConnectionTimeout(10000)
                    .withSocketTimeout(60000)
                    .build();

            final Map<String, String> queryParamMap = new HashMap<>();

            queryParamMap.put("q", "*:*");
            queryParamMap.put("fl", "*,dist:geodist()"); //查询的结果中添加距离
            queryParamMap.put("fq", "{!geofilt}"); //距离过滤函数
            queryParamMap.put("pt", point); //当前经纬度
            queryParamMap.put("sfield", "point"); //经纬度的字段
            queryParamMap.put("d", distance.toString()); //千米

            queryParamMap.put("start", "0");//记录开始位置
            queryParamMap.put("rows", String.valueOf(count));//查询的行数

            queryParamMap.put("sort", "geodist() asc");  //根据距离排序：由近到远

            MapSolrParams mapSolrParams = new MapSolrParams(queryParamMap);
            final QueryResponse response = httpSolrClient.query("poi", mapSolrParams);
            documents = response.getResults();

            String requestUrl = response.getRequestUrl();
            System.err.println("requestUrl:"+requestUrl);
            System.err.println("数量：" + documents.getNumFound());
            System.err.println("solr-time--1:" + (System.currentTimeMillis() - time));
            for (SolrDocument solrDocument : documents) {
                Poi poi = SolrUtils.solrDocumentToPojo(solrDocument, Poi.class);

                InterestPointResult poiResult = new InterestPointResult();

                poiResult.setName(poi.getName());

                List<String> address = new ArrayList<>();
                if (poi.getDelivery_line() != null) {
                    address.add(poi.getDelivery_line());
                }
                if (poi.getCity() != null) {
                    address.add(poi.getCity());
                }
                if (poi.getState() != null) {
                    address.add(poi.getState());
                }
                if (poi.getZip() != null) {
                    address.add(poi.getZip());
                }
                if (address.size() > 0) {
                    poiResult.setAddress(String.join(", ", address));
                }
                if (poi.getPhone() != null) {
                    poiResult.setPhone(poi.getPhone());
                }
                if (poi.getLatitude() != null) {
                    poiResult.setLatitude(poi.getLatitude());
                }
                if (poi.getLongitude() != null) {
                    poiResult.setLongitude(poi.getLongitude());
                }
                if (poi.getPrimary() != null) {
                    poiResult.setCategories(new HashSet(poi.getPrimary()));
                }
                if (poi.getDist() != null) {
                    poiResult.setDist(poi.getDist());
                }
                list.add(poiResult);
            }

            httpSolrClient.close();
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.err.println("solr-time:" + (System.currentTimeMillis() - time));

        return list;
    }

    /***
     * 验证查询类型参数是否正确
     * @param action 查询类型
     * @param keyword 查询关键字
     * @throws CustomException
     */
    private void validateSearchType(String action, String keyword) throws CustomException {
        if (!StringUtils.isEmpty(action) && !StringUtils.isEmpty(keyword)) {
            if (action.equalsIgnoreCase("zip")) {
                if (keyword.length() != 5) {
                    throw new CustomException(ResultCode.HOUSE_ILLEGALITY_ZIPCODE);
                }
            } else if (action.equalsIgnoreCase("address")) {
                if (keyword.length() < 3) {
                    throw new CustomException(ResultCode.HOUSE_ADDRESS_LENGTH_SHORTAGE);
                }
            } else if (action.equalsIgnoreCase("city")) {
                if (keyword.length() < 3) {
                    throw new CustomException(ResultCode.HOUSE_CITY_LENGTH_SHORTAGE);
                }
            } else {
                throw new CustomException(ResultCode.UNSUPPORTED_SEARCH_TYPE);
            }
        }
    }
}
